#ifndef MACROS_HPP
#define MACROS_HPP
#include <string>
#include <vector>
typedef std::vector<size_t> __;
#define Inject(T, N) (size_t)(&reinterpret_cast<char const volatile&>(((T*)0)->N))
namespace orm {
  template <typename N, class T> inline N& getIdex(T& a, size_t i) {
    return *reinterpret_cast<N*>(reinterpret_cast<char*>(&a) + a.$[i]);
  }
  template<typename T> const char* getObjectName() {
    const char* s = typeid(T).name();
#if _WIN32
    while (*++s != 0x20); return ++s;
#else
    while (*s < 0x3a && *s++ != 0x24) {}; return s;
#endif
  }
}
#define EXP(O) O
#ifdef _MSC_VER
#define ARGS_HELPER(_,_64,_63,_62,_61,_60,_59,_58,_57,_56,_55,_54,_53,_52,_51,_50,_49,_48,_47,_46,_45,_44,_43,_42,_41,_40,_39,_38,_37,_36,_35,_34,_33,_32,_31,_30,_29,_28,_27,_26,_25,_24,_23,_22,_21,_20,_19,_18,_17,_16,_15,_14,_13,_12,_11,_10,_9,_8,_7,_6,_5,_4,_3,_2,_1,N,...) N
#define NUM_ARGS(...) EXP(ARGS_HELPER(0, __VA_ARGS__ ,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0))
#else
#define ARGS_HELPER(_,_64,_63,_62,_61,_60,_59,_58,_57,_56,_55,_54,_53,_52,_51,_50,_49,_48,_47,_46,_45,_44,_43,_42,_41,_40,_39,_38,_37,_36,_35,_34,_33,_32,_31,_30,_29,_28,_27,_26,_25,_24,_23,_22,_21,_20,_19,_18,_17,_16,_15,_14,_13,_12,_11,_10,_9,_8,_7,_6,_5,_4,_3,_2,_1,N,...) N
#define NUM_ARGS(...) ARGS_HELPER(0, __VA_ARGS__ ,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)
#endif
#define PROTO_0(o)
#define PROTO_1(o,k)      Inject(o, k)
#define PROTO_2(o,k,...)  Inject(o, k), EXP(PROTO_1(o,__VA_ARGS__))
#define PROTO_3(o,k,...)  Inject(o, k), EXP(PROTO_2(o,__VA_ARGS__))
#define PROTO_4(o,k,...)  Inject(o, k), EXP(PROTO_3(o,__VA_ARGS__))
#define PROTO_5(o,k,...)  Inject(o, k), EXP(PROTO_4(o,__VA_ARGS__))
#define PROTO_6(o,k,...)  Inject(o, k), EXP(PROTO_5(o,__VA_ARGS__))
#define PROTO_7(o,k,...)  Inject(o, k), EXP(PROTO_6(o,__VA_ARGS__))
#define PROTO_8(o,k,...)  Inject(o, k), EXP(PROTO_7(o,__VA_ARGS__))
#define PROTO_9(o,k,...)  Inject(o, k), EXP(PROTO_8(o,__VA_ARGS__))
#define PROTO_10(o,k,...) Inject(o, k), EXP(PROTO_9(o,__VA_ARGS__))
#define PROTO_11(o,k,...) Inject(o, k), EXP(PROTO_10(o,__VA_ARGS__))
#define PROTO_12(o,k,...) Inject(o, k), EXP(PROTO_11(o,__VA_ARGS__))
#define PROTO_13(o,k,...) Inject(o, k), EXP(PROTO_12(o,__VA_ARGS__))
#define PROTO_14(o,k,...) Inject(o, k), EXP(PROTO_13(o,__VA_ARGS__))
#define PROTO_15(o,k,...) Inject(o, k), EXP(PROTO_14(o,__VA_ARGS__))
#define PROTO_16(o,k,...) Inject(o, k), EXP(PROTO_15(o,__VA_ARGS__))
#define PROTO_17(o,k,...) Inject(o, k), EXP(PROTO_16(o,__VA_ARGS__))
#define PROTO_18(o,k,...) Inject(o, k), EXP(PROTO_17(o,__VA_ARGS__))
#define PROTO_19(o,k,...) Inject(o, k), EXP(PROTO_18(o,__VA_ARGS__))
#define PROTO_20(o,k,...) Inject(o, k), EXP(PROTO_19(o,__VA_ARGS__))
#define PROTO_21(o,k,...) Inject(o, k), EXP(PROTO_20(o,__VA_ARGS__))
#define PROTO_22(o,k,...) Inject(o, k), EXP(PROTO_21(o,__VA_ARGS__))
#define PROTO_23(o,k,...) Inject(o, k), EXP(PROTO_22(o,__VA_ARGS__))
#define PROTO_24(o,k,...) Inject(o, k), EXP(PROTO_23(o,__VA_ARGS__))
#define PROTO_25(o,k,...) Inject(o, k), EXP(PROTO_24(o,__VA_ARGS__))
#define PROTO_26(o,k,...) Inject(o, k), EXP(PROTO_25(o,__VA_ARGS__))
#define PROTO_27(o,k,...) Inject(o, k), EXP(PROTO_26(o,__VA_ARGS__))
#define PROTO_28(o,k,...) Inject(o, k), EXP(PROTO_27(o,__VA_ARGS__))
#define PROTO_29(o,k,...) Inject(o, k), EXP(PROTO_28(o,__VA_ARGS__))
#define PROTO_30(o,k,...) Inject(o, k), EXP(PROTO_29(o,__VA_ARGS__))
#define PROTO_31(o,k,...) Inject(o, k), EXP(PROTO_30(o,__VA_ARGS__))
#define PROTO_32(o,k,...) Inject(o, k), EXP(PROTO_31(o,__VA_ARGS__))
#define PROTO_N1(o,N,...) EXP(PROTO_##N(o,__VA_ARGS__))
#define PROTO_N(o,N,...) PROTO_N1(o,N,__VA_ARGS__)
//REGIST(Tab, id, kg, date);
#define REGIST(o,...) template<> const __ o::$={ PROTO_N(o,NUM_ARGS(__VA_ARGS__),__VA_ARGS__) };

#define ATTR_0()
#define ATTR_1(k)      k(#k);
#define ATTR_2(k,...)  k(#k), EXP(ATTR_1(__VA_ARGS__))
#define ATTR_3(k,...)  k(#k), EXP(ATTR_2(__VA_ARGS__))
#define ATTR_4(k,...)  k(#k), EXP(ATTR_3(__VA_ARGS__))
#define ATTR_5(k,...)  k(#k), EXP(ATTR_4(__VA_ARGS__))
#define ATTR_6(k,...)  k(#k), EXP(ATTR_5(__VA_ARGS__))
#define ATTR_7(k,...)  k(#k), EXP(ATTR_6(__VA_ARGS__))
#define ATTR_8(k,...)  k(#k), EXP(ATTR_7(__VA_ARGS__))
#define ATTR_9(k,...)  k(#k), EXP(ATTR_8(__VA_ARGS__))
#define ATTR_10(k,...) k(#k), EXP(ATTR_9(__VA_ARGS__))
#define ATTR_11(k,...) k(#k), EXP(ATTR_10(__VA_ARGS__))
#define ATTR_12(k,...) k(#k), EXP(ATTR_11(__VA_ARGS__))
#define ATTR_13(k,...) k(#k), EXP(ATTR_12(__VA_ARGS__))
#define ATTR_14(k,...) k(#k), EXP(ATTR_13(__VA_ARGS__))
#define ATTR_15(k,...) k(#k), EXP(ATTR_14(__VA_ARGS__))
#define ATTR_16(k,...) k(#k), EXP(ATTR_15(__VA_ARGS__))
#define ATTR_17(k,...) k(#k), EXP(ATTR_16(__VA_ARGS__))
#define ATTR_18(k,...) k(#k), EXP(ATTR_17(__VA_ARGS__))
#define ATTR_19(k,...) k(#k), EXP(ATTR_18(__VA_ARGS__))
#define ATTR_20(k,...) k(#k), EXP(ATTR_19(__VA_ARGS__))
#define ATTR_21(k,...) k(#k), EXP(ATTR_20(__VA_ARGS__))
#define ATTR_22(k,...) k(#k), EXP(ATTR_21(__VA_ARGS__))
#define ATTR_23(k,...) k(#k), EXP(ATTR_22(__VA_ARGS__))
#define ATTR_24(k,...) k(#k), EXP(ATTR_23(__VA_ARGS__))
#define ATTR_25(k,...) k(#k), EXP(ATTR_24(__VA_ARGS__))
#define ATTR_26(k,...) k(#k), EXP(ATTR_25(__VA_ARGS__))
#define ATTR_27(k,...) k(#k), EXP(ATTR_26(__VA_ARGS__))
#define ATTR_28(k,...) k(#k), EXP(ATTR_27(__VA_ARGS__))
#define ATTR_29(k,...) k(#k), EXP(ATTR_28(__VA_ARGS__))
#define ATTR_30(k,...) k(#k), EXP(ATTR_29(__VA_ARGS__))
#define ATTR_31(k,...) k(#k), EXP(ATTR_30(__VA_ARGS__))
#define ATTR_32(k,...) k(#k), EXP(ATTR_31(__VA_ARGS__))
/** Single init **/
#define ATTRS_N1(N,...) EXP(ATTR_##N(__VA_ARGS__))
#define ATTRS_N(N,...) ATTRS_N1(N,__VA_ARGS__)

//----------------------------------------------------------
#define STR_0(o)
#define STR_2(o,k,v)      const char* o::$##k = v;
#define STR_4(o,k,v,...)  const char* o::$##k = v; EXP(STR_2(o,__VA_ARGS__))
#define STR_6(o,k,v,...)  const char* o::$##k = v; EXP(STR_4(o,__VA_ARGS__))
#define STR_8(o,k,v,...)  const char* o::$##k = v; EXP(STR_6(o,__VA_ARGS__))
#define STR_10(o,k,v,...) const char* o::$##k = v; EXP(STR_8(o,__VA_ARGS__))
#define STR_12(o,k,v,...) const char* o::$##k = v; EXP(STR_10(o,__VA_ARGS__))
#define STR_14(o,k,v,...) const char* o::$##k = v; EXP(STR_12(o,__VA_ARGS__))
#define STR_16(o,k,v,...) const char* o::$##k = v; EXP(STR_14(o,__VA_ARGS__))
#define STR_18(o,k,v,...) const char* o::$##k = v; EXP(STR_16(o,__VA_ARGS__))
#define STR_20(o,k,v,...) const char* o::$##k = v; EXP(STR_18(o,__VA_ARGS__))
#define STR_22(o,k,v,...) const char* o::$##k = v; EXP(STR_20(o,__VA_ARGS__))
#define STR_24(o,k,v,...) const char* o::$##k = v; EXP(STR_22(o,__VA_ARGS__))
#define STR_26(o,k,v,...) const char* o::$##k = v; EXP(STR_24(o,__VA_ARGS__))
#define STR_28(o,k,v,...) const char* o::$##k = v; EXP(STR_26(o,__VA_ARGS__))
#define STR_30(o,k,v,...) const char* o::$##k = v; EXP(STR_28(o,__VA_ARGS__))
#define STR_32(o,k,v,...) const char* o::$##k = v; EXP(STR_30(o,__VA_ARGS__))
#define STR_34(o,k,v,...) const char* o::$##k = v; EXP(STR_32(o,__VA_ARGS__))
#define STR_36(o,k,v,...) const char* o::$##k = v; EXP(STR_34(o,__VA_ARGS__))
#define STR_38(o,k,v,...) const char* o::$##k = v; EXP(STR_36(o,__VA_ARGS__))
#define STR_40(o,k,v,...) const char* o::$##k = v; EXP(STR_38(o,__VA_ARGS__))
#define STR_42(o,k,v,...) const char* o::$##k = v; EXP(STR_40(o,__VA_ARGS__))
#define STR_44(o,k,v,...) const char* o::$##k = v; EXP(STR_42(o,__VA_ARGS__))
#define STR_46(o,k,v,...) const char* o::$##k = v; EXP(STR_44(o,__VA_ARGS__))
#define STR_48(o,k,v,...) const char* o::$##k = v; EXP(STR_46(o,__VA_ARGS__))
#define STR_50(o,k,v,...) const char* o::$##k = v; EXP(STR_48(o,__VA_ARGS__))
#define STR_52(o,k,v,...) const char* o::$##k = v; EXP(STR_50(o,__VA_ARGS__))
#define STR_54(o,k,v,...) const char* o::$##k = v; EXP(STR_52(o,__VA_ARGS__))
#define STR_56(o,k,v,...) const char* o::$##k = v; EXP(STR_54(o,__VA_ARGS__))
#define STR_58(o,k,v,...) const char* o::$##k = v; EXP(STR_56(o,__VA_ARGS__))
#define STR_60(o,k,v,...) const char* o::$##k = v; EXP(STR_58(o,__VA_ARGS__))
#define STR_62(o,k,v,...) const char* o::$##k = v; EXP(STR_60(o,__VA_ARGS__))
#define STR_64(o,k,v,...) const char* o::$##k = v; EXP(STR_62(o,__VA_ARGS__))
#define STR_N1(o,N,...) EXP(STR_##N(o,__VA_ARGS__))
#define STR_N(o,N,...) STR_N1(o,N,__VA_ARGS__)
//REGIST_CUSTOM(Tab, id, "id", kg, "kg", date, "dates");
#define REGIST_CUSTOM(o,...)\
    STR_N(o,NUM_ARGS(__VA_ARGS__),__VA_ARGS__)

#endif
